"""
报价业务处理模块
"""
import time
from datetime import datetime
from typing import Dict, List, Callable, Any
from functools import wraps
from reqapi.confirm_and_send_offer import ConfirmAndSendOfferApi
from reqapi.query_offers_status import QueryOffersStatusApi
from com.db.order_record_manager import OrderRecordManager
from com.utils.logger import get_logger
import random

logger = get_logger("OfferCommodity")

def retry_on_failure(max_retries: int = 3, retry_delay: float = 1.0, 
                    retryable_exceptions: tuple = (Exception,)) -> Callable:
    """
    重试装饰器
    Args:
        max_retries: 最大重试次数
        retry_delay: 重试间隔（秒）
        retryable_exceptions: 需要重试的异常类型
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args, **kwargs) -> Any:
            last_exception = None
            for attempt in range(max_retries):
                try:
                    result = func(*args, **kwargs)
                    # 检查返回结果是否表示失败
                    if isinstance(result, dict) and not result.get("success"):
                        if attempt == max_retries - 1:
                            return result
                        time.sleep(retry_delay)
                        continue
                    return result
                except retryable_exceptions as e:
                    last_exception = e
                    if attempt == max_retries - 1:
                        break
                    time.sleep(retry_delay)
            
            # 所有重试都失败了
            error_msg = f"{func.__name__} 失败，重试 {max_retries} 次后仍然失败: {str(last_exception)}"
            return {"success": False, "message": error_msg}
        return wrapper
    return decorator

class OfferCommodity:
    def __init__(self, device_token=None, device_id=None, auth_token=None, uk=None):
        """
        初始化报价处理类
        Args:
            device_token: 设备token
            device_id: 设备ID
            auth_token: 认证token
            uk: 用户标识
        """
        self.device_token = device_token
        self.device_id = device_id
        self.auth_token = auth_token
        self.uk = uk
        self.order_manager = OrderRecordManager()

    def process_offer(self, send_order_no_list: List[str], record_ids: List[int], max_offer_times: int = 5) -> Dict:
        """
        处理报价
        Args:
            send_order_no_list: 需要发送报价的订单号列表
            record_ids: 订单记录ID列表
            max_offer_times: 最大发送报价次数
        Returns:
            Dict: 处理结果
        """
        try:
            # 1. 确认发货并发送报价
            current_offer_times = 1  # 当前发送报价次数
            
            logger.info("[处理报价] 开始处理报价请求")
            logger.info("[处理报价] 参数信息:")
            logger.info(f"  - 订单列表: {send_order_no_list}")
            logger.info(f"  - 记录ID列表: {record_ids}")
            logger.info(f"  - 最大重试次数: {max_offer_times}")
            
            logger.info(f"[确认发货] 第{current_offer_times}次发送报价")
            logger.info(f"[确认发货] 订单列表: {send_order_no_list}")
            offer_result = self._confirm_and_send_offer(send_order_no_list)
            logger.info(f"[确认发货] 发送报价结果: {offer_result}")
            
            # 更新报价次数
            logger.info(f"[更新报价] 更新数据库中的报价次数为: {current_offer_times}")
            for record_id in record_ids:
                logger.info(f"[更新报价] 更新记录 {record_id}")
                self.order_manager.update_record(int(record_id), {"offer_times": current_offer_times})
            logger.info("[更新报价] 报价次数更新完成")
            
            if not offer_result["success"]:
                logger.error(f"[确认发货] 发送报价失败: {offer_result['message']}")
                return offer_result
                
            while True:
                # 2. 循环查询报价状态
                max_query_times = 5  # 最大查询次数
                logger.info(f"[查询报价] 开始循环查询报价状态")
                logger.info(f"[查询报价] 参数信息:")
                logger.info(f"  - 订单列表: {send_order_no_list}")
                logger.info(f"  - 最大查询次数: {max_query_times}")
                
                for i in range(max_query_times):
                    logger.info(f"[查询报价] 第{i + 1}次查询")
                    offer_status = self._query_offers_status(send_order_no_list)
                    
                    if not offer_status["success"]:
                        logger.error(f"[查询报价] 查询失败: {offer_status['message']}")
                        return offer_status
                    
                    # 解析报价结果
                    offer_data = offer_status.get("data", {})
                    logger.info(f"[查询报价] 状态详情:")
                    logger.info(f"  - 总数: {offer_data.get('totalNum', 0)}")
                    logger.info(f"  - 发送成功: {offer_data.get('sendSuccessNum', 0)}")
                    logger.info(f"  - 发送失败: {offer_data.get('sendFailedNum', 0)}")
                    logger.info(f"  - 进行中: {offer_data.get('offerIngNum', 0)}")
                    
                    # 获取详细消息
                    offer_messages = offer_data.get("offerMessagesList", [])
                    if offer_messages:
                        messages = []
                        logger.info(f"[查询报价] 报价消息详情:")
                        for msg in offer_messages:
                            message = msg.get("message", "")
                            order_num = msg.get("orderNum", "")
                            logger.info(f"  - {message}(订单号: {order_num})")
                            messages.append(f"{message}({order_num})")
                    
                    # 获取发送报价消息
                    send_messages = offer_data.get("sendOfferMessagesList", [])
                    if send_messages:
                        messages = []
                        logger.info(f"[查询报价] 发送报价消息详情:")
                        for msg in send_messages:
                            message = msg.get("message", "")
                            count = msg.get("count", "")
                            logger.info(f"  - {message}(数量: {count})")
                            messages.append(f"{message}({count})")
                    
                    # 判断报价状态
                    if offer_data.get("sendSuccessNum", 0) > 0:
                        logger.info("[查询报价] 检测到报价发送成功")
                        # 更新数据库中的报价状态为成功
                        current_time = datetime.now().isoformat()
                        logger.info(f"[更新报价状态] 开始更新数据库状态")
                        logger.info(f"[更新报价状态] 更新信息:")
                        logger.info(f"  - 状态: 成功(2)")
                        logger.info(f"  - 时间: {current_time}")
                        
                        for record_id in record_ids:
                            logger.info(f"[更新报价状态] 更新记录 {record_id}")
                            self.order_manager.update_offer_status(
                                record_id=int(record_id),
                                status=2,  # 2表示报价成功
                                offer_at=current_time,
                                desc=None
                            )
                        logger.info("[更新报价状态] 所有记录更新完成")
                        return {"success": True, "message": "报价发送成功"}
                        
                    if offer_data.get("sendFailedNum", 0) > 0:
                        # 获取失败原因
                        fail_messages = [msg.get("message", "") for msg in offer_messages]
                        error_desc = "、".join(fail_messages) if fail_messages else "未知原因"
                        logger.warning(f"[查询报价] 检测到报价发送失败")
                        logger.warning(f"[查询报价] 失败原因: {error_desc}")
                        
                        # 如果已经达到最大发送次数，则更新状态为失败
                        if current_offer_times >= max_offer_times:
                            logger.warning(f"[查询报价] 已达到最大发送次数({max_offer_times}次)")
                            logger.info("[查询报价] 准备更新数据库状态为失败")
                            
                            # 更新数据库中的报价状态为失败
                            current_time = datetime.now().isoformat()
                            logger.info(f"[更新报价状态] 更新信息:")
                            logger.info(f"  - 状态: 失败(0)")
                            logger.info(f"  - 时间: {current_time}")
                            logger.info(f"  - 失败原因: {error_desc}")
                            
                            for record_id in record_ids:
                                logger.info(f"[更新报价状态] 更新记录 {record_id}")
                                self.order_manager.update_offer_status(
                                    record_id=int(record_id),
                                    status=0,  # 0表示报价失败
                                    offer_at=current_time,
                                    desc=error_desc
                                )
                            logger.info("[更新报价状态] 所有记录更新完成")
                            return {"success": False, "message": f"报价失败: {error_desc}"}
                        
                        # 未达到最大次数，继续重试
                        current_offer_times += 1
                        logger.info(f"[重试报价] 准备第{current_offer_times}次发送报价")
                        logger.info(f"[重试报价] 订单列表: {send_order_no_list}")
                        offer_result = self._confirm_and_send_offer(send_order_no_list)
                        logger.info(f"[重试报价] 发送报价结果: {offer_result}")
                        
                        # 更新报价次数
                        logger.info(f"[更新报价] 更新数据库中的报价次数为: {current_offer_times}")
                        for record_id in record_ids:
                            logger.info(f"[更新报价] 更新记录 {record_id}")
                            self.order_manager.update_record(int(record_id), {"offer_times": current_offer_times})
                        logger.info("[更新报价] 报价次数更新完成")
                        
                        # 即使发送失败也继续查询
                        if not offer_result["success"]:
                            logger.warning(f"[重试报价] 发送报价失败: {offer_result['message']}")
                            
                        # 重新发送后等待10-20秒
                        wait_time = random.uniform(10, 20)
                        logger.info(f"[查询报价] 准备重新开始查询，等待{wait_time:.1f}秒")
                        time.sleep(wait_time)
                        break  # 跳出查询循环，重新开始查询
                        
                    if offer_data.get("offerIngNum", 0) > 0:
                        wait_time = random.uniform(10, 20)
                        logger.info(f"[查询报价] 报价进行中，等待{wait_time:.1f}秒后继续查询")
                        time.sleep(wait_time)
                        continue
                
                # 如果是因为查询次数用完而跳出循环
                if i == max_query_times - 1:
                    logger.warning(f"[查询报价] 已达到最大查询次数({max_query_times}次)")
                    return {"success": False, "message": "查询报价超时"}
                    
                # 如果是因为需要重新发送报价而跳出循环，则继续外层循环
                if offer_data.get("sendFailedNum", 0) > 0:
                    logger.info(f"[查询报价] 检测到报价失败，继续外层循环重新发送报价")
                    continue
                    
                # 其他情况，返回异常
                logger.error(f"[查询报价] 出现未知状态，返回异常")
                return {"success": False, "message": "查询报价状态异常"}
                
        except Exception as e:
            error_msg = f"处理报价失败: {str(e)}"
            logger.error(f"[处理报价] 发生异常: {error_msg}")
            return {"success": False, "message": error_msg}

    @retry_on_failure(max_retries=3, retry_delay=1.0)
    def _confirm_and_send_offer(self, send_order_no_list: List[str]) -> Dict:
        """
        确认发货并发送报价
        Args:
            send_order_no_list: 需要发送报价的订单号列表
        Returns:
            Dict: 发送结果
        """
        logger.info(f"[确认发货API] 开始调用API，参数: {send_order_no_list}")
        api = ConfirmAndSendOfferApi(
            device_token=self.device_token,
            device_id=self.device_id,
            auth_token=self.auth_token,
            uk=self.uk
        )
        logger.info(f"[确认发货API] 初始化API对象，device_token={self.device_token}, device_id={self.device_id}")
        
        try:
            result = api.execute(send_order_no_list=send_order_no_list)
            logger.info(f"[确认发货API] API响应原始数据: {result}")
            logger.info(f"[确认发货API] API调用成功")
            return {"success": True, "data": result}
        except Exception as e:
            error_msg = f"确认发货失败: {str(e)}"
            logger.error(f"[确认发货API] API调用异常: {str(e)}")
            return {"success": False, "message": error_msg}

    @retry_on_failure(max_retries=3, retry_delay=1.0)
    def _query_offers_status(self, send_order_no_list: List[str]) -> Dict:
        """
        查询报价状态
        Args:
            send_order_no_list: 需要查询的订单号列表
        Returns:
            Dict: 查询结果
        """
        try:
            logger.info(f"[查询报价API] 开始调用API，参数: {send_order_no_list}")
            api = QueryOffersStatusApi(
                device_token=self.device_token,
                device_id=self.device_id,
                auth_token=self.auth_token,
                uk=self.uk
            )
            logger.info(f"[查询报价API] 初始化API对象，device_token={self.device_token}, device_id={self.device_id}")
            
            result = api.execute(send_order_no_list)
            logger.info(f"[查询报价API] API响应原始数据: {result}")
            
            # API直接返回数据，不需要判断code
            if isinstance(result, dict):
                logger.info(f"[查询报价API] API调用成功，响应数据类型正确")
                
                # 记录响应中的关键数据
                total_num = result.get('totalNum', 0)
                success_num = result.get('sendSuccessNum', 0)
                failed_num = result.get('sendFailedNum', 0)
                ing_num = result.get('offerIngNum', 0)
                logger.info(f"[查询报价API] 响应数据统计: 总数={total_num}, 成功={success_num}, 失败={failed_num}, 进行中={ing_num}")
                
                # 记录报价消息
                offer_messages = result.get("offerMessagesList", [])
                if offer_messages:
                    logger.info(f"[查询报价API] 报价消息列表:")
                    for msg in offer_messages:
                        message = msg.get("message", "")
                        order_num = msg.get("orderNum", "")
                        logger.info(f"  - {message}(订单号: {order_num})")
                
                # 记录发送报价消息
                send_messages = result.get("sendOfferMessagesList", [])
                if send_messages:
                    logger.info(f"[查询报价API] 发送报价消息列表:")
                    for msg in send_messages:
                        message = msg.get("message", "")
                        count = msg.get("count", "")
                        logger.info(f"  - {message}(数量: {count})")
                
                return {"success": True, "data": result}
                
            logger.error(f"[查询报价API] API返回数据格式错误，期望dict类型，实际类型: {type(result)}")
            return {"success": False, "message": "查询报价状态失败: 返回数据格式错误"}
            
        except Exception as e:
            logger.error(f"[查询报价API] API调用异常: {str(e)}")
            error_msg = f"查询报价状态失败: {str(e)}"
            return {"success": False, "message": error_msg}
